<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="test"></div>
	
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/17.0.1/react.development.js"></script>
	<!-- 引入react-dom，用于支持react操作DOM -->
	<script type="text/javascript" src="../js/17.0.1/react-dom.development.js"></script>
	<!-- 引入babel，用于将jsx转为js -->
	<script type="text/javascript" src="../js/17.0.1/babel.min.js"></script>
	<!-- 引入prop-types，用于对组件标签属性进行限制 -->
	<script type="text/javascript" src="../js/17.0.1/prop-types.js"></script>

	<script type="text/babel">
        //计数组件
        class Count extends React.Component{
            constructor(props){
                super(props)
                this.state={sum:0};
            }
            
            add = ()=>{
                const {sum} = this.state;
                this.setState({
                    sum:sum+1,
                })
            }

            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }
            
            force = ()=>{
                this.forceUpdate();
            }

			//组件将要挂载或者更新时调用,返回得对象里面如果有初始化时的键名
            //一般用于返回值只取决于props或者state的状态,使用很少
            // static getDerivedStateFromProps(props,state){
            //     console.log('getDerivedStateFromProps');
            //     return state;
            // }

            // 在render和componentDidUpdate之间调用
            // 必须返回快照值或者null
            // 使得组件能在发生更改之前从DOM中捕获一些信息，（滚动位置，输入框聚焦）。
            // 此生命周期的返回值将作为参数传递给componentDidUpdate()。
            // 此用法也不常见
            getSnapshotBeforeUpdate(preProps,preState){
                console.log('getSnapshotBeforeUpdate',preProps,preState);
                return null;
            }

            //组件挂载完毕的钩子
			componentDidMount(){
				console.log('Count---componentDidMount');
			}

            //组件将要卸载的钩子
			componentWillUnmount(){
				console.log('Count---componentWillUnmount');
			}

            //控制组件更新的“阀门”
			shouldComponentUpdate(){
				console.log('Count---shouldComponentUpdate');
				return true;//真可以继续，否则就拦截掉
			}

            //组件更新完毕的钩子
			componentDidUpdate(preProps,preState,snapshot){
				console.log('Count---componentDidUpdate',preProps,preState,snapshot);
			}

            render(){
                const {sum} = this.state;
                return (
                    <div>
                        <h1>当前求和为：{sum}</h1>
                        <button onClick={this.add}>点我加1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不更改任何状态中的数据，强制更新一下</button>
                    </div>
                )
            }
        }
        //子组件B
        class B extends React.Component{
            //接收到新的props参数的时候会调用这个钩子
            UNSAFE_componentWillReceiveProps(props){
                console.log('B---componentWillReceiveProps',props)
            }

            render(){
                return (
                    <h2>车子名为{this.props.carName}</h2>
                )
            }
        }
        //父组件A
        class A extends React.Component{
            state = {carName:'奔驰'};

            changeCar = ()=>{
                this.setState({
                    carName:'奥迪',
                })
            }

            render(){
                return (
                    <div>
                        <B carName={this.state.carName}/>
                        <button onClick={this.changeCar}>换车</button>
                    </div>
                )
            }
        }
        // ReactDOM.render(<Life />,document.getElementById('test'))
        ReactDOM.render(<Count />,document.getElementById('test'));
    </script>
</body>
</html>